code source game Bi-a 3D

23.677 lượt xem;
1 using UnityEngine;
2 using
ThreeDPool.EventHandlers;
3 using
ThreeDPool.Managers;
4
5 namespace
ThreeDPool.Controllers
6 {
7     
public class CueBallController : MonoBehaviour
8     {
9         
public enum CueBallType
10         {
11             White =
0,
12             Yellow,
13             Blue,
14             Red,
15             Purple,
16             Orange,
17             Green,
18             Burgandy,
19             Black,
20             Striped_Yellow,
21             Striped_Blue,
22             Striped_Red,
23             Striped_Purple,
24             Striped_Orange,
25             Striped_Green,
26             Striped_Burgandy,
27         }
28
29         
[SerializeField]
30         
float _force = 30f;
31
32         
[SerializeField]
33         CueBallType _ballType = CueBallType.White;
34
35         
// keep track of the current event
36         
private CueBallActionEvent.States _currState;
37
38         
private Vector3 _initialPos;
39
40         
// flag that diffrentiates between the ball that is pocketed in the current turn versus ball that is pocketed in the earlier turn
41         
// this helps in scoring
42         
public bool IsPocketedInPrevTurn;
43
44         
public CueBallType BallType { get { return _ballType; } }
45
46
47         
private void Start()
48         {
49             
// record the intial position so that they could be placed in their original position if it goes out of table
50             _initialPos = transform.position;
51
52             EventManager.Subscribe(
typeof(CueBallActionEvent).Name, OnCueBallEvent);
53             EventManager.Subscribe(
typeof(GameStateEvent).Name, OnGameStateEvent);
54         }
55
56         
private void OnDestroy()
57         {
58             EventManager.Unsubscribe(
typeof(CueBallActionEvent).Name, OnCueBallEvent);
59             EventManager.Unsubscribe(
typeof(GameStateEvent).Name, OnGameStateEvent);
60         }
61
62         
private void OnCueBallEvent(object sender, IGameEvent gameEvent)
63         {
64             CueBallActionEvent actionEvent = (CueBallActionEvent)gameEvent;
65             
switch(actionEvent.State)
66             {
67                 
case CueBallActionEvent.States.Stationary:
68                     {
69                         
// change the curr state to default now
70                         _currState = CueBallActionEvent.States.Default;
71                     }
72                     
break;
73             }
74         }
75
76         
private void OnGameStateEvent(object sender, IGameEvent gameEvent)
77         {
78             GameStateEvent gameStateEvent = (GameStateEvent)gameEvent;
79             
switch (gameStateEvent.GameState)
80             {
81                 
case GameStateEvent.State.Play:
82                     {
83                         PlaceBallInInitialPos();
84                     }
85                     
break;
86             }
87         }
88
89         
private void OnTriggerEnter(Collider collider)
90         {
91             CueController cueController = collider.gameObject.transform.parent.GetComponent<CueController>();
92
93             
// confirm if the ball is actually hit by a ball
94             
if (cueController != null)
95             {
96                 
// ball is hit by the cue
97                 
if (_ballType == CueBallType.White)
98                 {
99                     
// notify that the ball is hit
100                     EventManager.Notify(
typeof(CueBallActionEvent).Name, this, new CueBallActionEvent() { State = CueBallActionEvent.States.Striked });
101
102                     
// set the current state
103                     _currState = CueBallActionEvent.States.Striked;
104
105                     
// whats the force gathered to hit
106                     
float forceGatheredToHit = cueController.ForceGatheredToHit;
107
108                     
// set the ball rolling with gathered force
109                     OnStriked(forceGatheredToHit);
110                 }
111             }
112         }
113
114         
private void OnCollisionEnter(Collision collision)
115         {
116             
if (collision.gameObject.layer == LayerMask.NameToLayer("Floor"))
117             {
118                 Debug.Log(
"Oncollision" + collision.gameObject.name);
119
120                 
// potted information is detected by PocketCollider
121                 
// if ball got potted,
122                 
// check if the ball potted is a cue ball, if yes then player looses the point and the cue is placed back in the table
123                 
// if not then its a point to the current player
124                 GameManager.Instance.AddToBallHitOutList(
this);
125             }
126         }

127
128         ///
<summary>
129         ///
ball goes through various lifecycle from default, placing to the coming back to stationary state after been striked
130         ///
</summary>
131         
private void FixedUpdate()
132         {
133             Rigidbody rigidbody = gameObject.GetComponent<Rigidbody>();
134             
if ((_currState == CueBallActionEvent.States.Placing) && rigidbody.IsSleeping())
135             {
136                 _currState = CueBallActionEvent.States.Default;
137             }
138             
else if ((_currState == CueBallActionEvent.States.Default) && (!rigidbody.IsSleeping()))
139             {
140                 
// number of balls striked in Play mode
141                 
if (GameManager.Instance.CurrGameState == GameManager.GameState.Play)
142                     GameManager.Instance.NumOfBallsStriked++;
143
144                 _currState = CueBallActionEvent.States.Striked;
145             }
146             
else if ((_currState == CueBallActionEvent.States.Striked) && (!rigidbody.IsSleeping()))
147             {
148                 _currState = CueBallActionEvent.States.InMotion;
149             }
150             
else if ((_currState == CueBallActionEvent.States.Striked) && (rigidbody.IsSleeping()))
151             {
152                 _currState = CueBallActionEvent.States.InMotion;
153             }
154             
else if ((_currState == CueBallActionEvent.States.InMotion) && rigidbody.IsSleeping())
155             {
156                 
// ball is come to rest after been striked, check for the status
157                 GameManager.Instance.ReadyForNextRound();
158
159                 _currState = CueBallActionEvent.States.Stationary;
160             }
161             
else
162             {
163                 
// do nothing
164             }
165         }

166
167         ///
<summary>
168         ///
OnStriked by Cue
169         ///
</summary>
170         ///
<param name="forceGathered">amount of force applied on the cue ball</param>
171         
private void OnStriked(float forceGathered)
172         {
173             
// only apply force on the white ball
174             
if (_ballType == CueBallType.White)
175             {
176                 GameManager.Instance.NumOfBallsStriked++;
177
178                 Rigidbody rigidBody = gameObject.GetComponent<Rigidbody>();
179                 rigidBody.AddForce(Camera.main.transform.forward * _force * forceGathered, ForceMode.Force);
180             }
181         }

182
183         ///
<summary>
184         ///
this function is called by the pockets collider in the pool table when a cue ball touches it
185         ///
</summary>
186         
public void BallPocketed()
187         {
188             GameManager.Instance.AddToBallPocketedList(
this);
189         }

190
191         ///
<summary>
192         ///
this function is called only while in practise mode
193         ///
</summary>
194         
public void PlaceBallInPosWhilePractise()
195         {
196             PlaceBallInInitialPos();
197
198             EventManager.Notify(
typeof(CueBallActionEvent).Name, this, new CueBallActionEvent() { State = CueBallActionEvent.States.Stationary });
199         }

200
201         ///
<summary>
202         ///
this function is been called whenever there is a reset of p
203         ///
</summary>
204         
public void PlaceBallInInitialPos()
205         {
206             
// place it a bit from top so that balls dont get placed within each other
207             transform.position =
new Vector3(_initialPos.x, _initialPos.y + 0.2f, _initialPos.z);
208
209             
// this flag resets after the completion of one complete round,
210             
// since the function is reused, and whenever there is a reset, it is safe to reset the flag here
211             IsPocketedInPrevTurn =
false;
212
213             _currState = CueBallActionEvent.States.Placing;
214             GameManager.Instance.NumOfBallsStriked =
0;
215         }
216     }
217 }


Gõ tìm kiếm nhanh...